package pres.moling.common.http;

import lombok.Data;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.net.*;
import java.net.http.HttpClient;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
 * @author yh
 * @apiNote HttpConnector配置器
 **/
@Data
public class HttpConnectorConfig {

    /**
     * Http版本，默认HTTP_2
     */
    private HttpClient.Version version = HttpClient.Version.HTTP_2;
    /**
     * 转发策略
     */
    private HttpClient.Redirect redirect = HttpClient.Redirect.NORMAL;
    /**
     * 线程池，默认5个连接
     */
    private Executor executor;
    /**
     * 认证信息
     */
    private Authenticator authenticator;
    /**
     * 代理信息
     */
    private ProxySelector proxySelector;
    /**
     * Cookies信息
     */
    private CookieManager cookieManager;
    /**
     * SSL连接信息
     */
    private SSLContext sslContext;
    /**
     * SSL连接参数
     */
    private SSLParameters sslParameters;
    /**
     * 连接超时时间，毫秒
     */
    private int connectTimeout = 10000;
    /**
     * 默认读取数据超时时间，毫秒
     */
    private int defaultReadTimeout = 1200000;
    /**
     * 默认Content-Type
     */
    private static final String defaultContentType = "application/json";
    /**
     * 默认内容编码
     */
    private Charset requestCode = StandardCharsets.UTF_8, responseCode = StandardCharsets.UTF_8;
    /**
     * 自定义头信息
     */
    private Map<String, String> headerMap;

    /**
     * 构造函数
     */
    public HttpConnectorConfig() {
        TrustManager[] trustAllCertificates = new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(X509Certificate[] x509Certificates, String s) {

                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] x509Certificates, String s) {

                    }

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[0];
                    }
                }
        };

        sslParameters = new SSLParameters();
        sslParameters.setEndpointIdentificationAlgorithm("");

        try {
            sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, trustAllCertificates, new SecureRandom());
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            e.printStackTrace();
        }
    }

    /**
     * 构造头文件
     *
     * @return 头文件信息
     */
    public String[] buildHeader() {
        return buildHeader(defaultContentType);
    }

    /**
     * 构造头文件参数，允许强制设定Content-Type
     *
     * @param contentType 强制的Content-Type
     * @return 头文件信息
     */
    public String[] buildHeader(String contentType) {
        if (headerMap == null) {
            headerMap = new HashMap<>();
            headerMap.put("Content-Type", contentType);
        } else {
            Set<String> headerKeys = headerMap.keySet();
            if (headerKeys.stream().noneMatch("Content-Type"::equalsIgnoreCase)) {
                headerMap.put("Content-Type", contentType);
            }
        }
        String[] result = new String[headerMap.size() * 2];
        int index = 0;
        for (Map.Entry<String, String> entry :
                headerMap.entrySet()) {
            result[index++] = entry.getKey();
            result[index++] = entry.getValue();
        }
        return result;
    }

    /**
     * 构建线程池，支持快捷构建默认线程池
     */
    public void buildExecutor() {
        if (executor == null) {
            this.executor = Executors.newFixedThreadPool(5);
        }
    }

    /**
     * 构建Cookie，支持快速构建默认Cookie
     */
    public void buildCookieManager() {
        if (this.cookieManager == null) {
            this.cookieManager = new CookieManager();
            cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
        }
    }




}